/**
 * 
 */
package com.neal.service.securities.authrity;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import com.neal.domain.securities.Resources;
import com.neal.domain.securities.Role;
import com.neal.service.securities.IResourceService;

/**
 * @author Neal
 * @version 1.0
 * @description
 */
public class SecurityMetadataSourceBean implements FilterInvocationSecurityMetadataSource {

	@Autowired
	private IResourceService resourceService;

	private ConcurrentHashMap<String, Collection<ConfigAttribute>> accessMap = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();

	@PostConstruct
	public void init() {

		List<Resources> allResources = resourceService.findAllResourcesFetchRole();
		if (allResources != null) {
			for (Resources resources : allResources) {
				Collection<ConfigAttribute> collection = new ArrayList<ConfigAttribute>();
				for (Role role : resources.getRoles()) {
					ConfigAttribute attribute = new SecurityConfig(role.getName());
					collection.add(attribute);
				}
				accessMap.put(resources.getUrl(), collection);
			}
		}
		// ConfigAttribute configAttribute = new SecurityConfig("ROLE_USER");
		// collection.add(configAttribute);
		//
		// accessMap.put("/messageList*", collection);
		// accessMap.put("/messagePost*", collection);
		// accessMap.put("/messageDelete*", collection);
		//
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.security.access.SecurityMetadataSource#getAttributes
	 * (java.lang.Object)
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

		RequestMatcher matcher = null;
		String requestUrl = null;
		for (Iterator<String> iterator = accessMap.keySet().iterator(); iterator.hasNext();) {
			requestUrl = iterator.next();
			matcher = new AntPathRequestMatcher(requestUrl);
			if (null != requestUrl && matcher.matches(request)) {
				return accessMap.get(requestUrl);
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.access.SecurityMetadataSource#
	 * getAllConfigAttributes()
	 */
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.security.access.SecurityMetadataSource#supports(java
	 * .lang.Class)
	 */
	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

	/**
	 * Remove Access (When remove Role)
	 * 
	 * @param key
	 */
	public void removeAccessAttribute(String key) {
		accessMap.remove(key);
	}

	/**
	 * Add Access (When Add Role)
	 * 
	 * @param key
	 */
	public void addAccessAttribute(String key, Collection<ConfigAttribute> attributes) {
		accessMap.put(key, attributes);
	}
}
